<template>
  <!-- 商品分类导航 -->
  <div class="type-nav">
    <!-- 事件委派，子元素的事件委派给父元素 -->
    <div
      class="container"
      @mouseenter="isShow = true"
      @mouseleave="leaveIndex()"
    >
      <h2 class="all">全部商品分类</h2>
      <nav class="nav">
        <a href="###">服装城</a>
        <a href="###">美妆馆</a>
        <a href="###">尚品汇超市</a>
        <a href="###">全球购</a>
        <a href="###">闪购</a>
        <a href="###">团购</a>
        <a href="###">有趣</a>
        <a href="###">秒杀</a>
      </nav>

      <!-- 
        思路：加动画->只有v-if/v-show命令的才可以加动画（利用显示与隐藏的瞬间来做动画）
        ->vue使用动画的方式：在这个元素外面加<transition></transition>
        ->加个name可以不用写v-开头的类选择器
        ->直接写类选择器来自定义动画
        ->注意类选择器要和sort平级，因为我并不是sort里面做动画，而用那三个来包含sort也不方便
          那就直接平级算了，够用就行
       -->
      <transition name="sort">
        <div class="sort" v-show="isShow">
          <div class="all-sort-list2" @click="goSearch">
            <!-- 三级嵌套循环的收获：for写在哪就说明哪个要循环
               这里它在页面上不是嵌套的，而是跟在后面的，其实就是里面一个循环
               在写for循环的时候尽量往外层写，这样就可以把里面的样式都包进去
          -->
            <div
              @mouseenter="changeIndex(c1.categoryId)"
              :class="{ curr: currentIndex === c1.categoryId }"
              v-for="c1 in categoryList"
              :key="c1.categoryId"
              class="item bo"
            >
              <h3>
                <a
                  :data-categoryName="c1.categoryName"
                  :data-category1Id="c1.categoryId"
                  >{{ c1.categoryName }}</a
                >
              </h3>
              <div class="item-list clearfix">
                <div
                  v-for="c2 in c1.categoryChild"
                  :key="c2.categoryId"
                  class="subitem"
                >
                  <dl class="fore">
                    <dt>
                      <a
                        :data-categoryName="c2.categoryName"
                        :data-category2Id="c2.categoryId"
                        >{{ c2.categoryName }}</a
                      >
                    </dt>
                    <dd>
                      <em v-for="c3 in c2.categoryChild" :key="c3.categoryId">
                        <a
                          :data-categoryName="c3.categoryName"
                          :data-category3Id="c3.categoryId"
                          >{{ c3.categoryName }}</a
                        >
                      </em>
                    </dd>
                  </dl>
                </div>
              </div>
            </div>
          </div>
        </div>
      </transition>
    </div>
  </div>
</template>

<script>
import { mapState } from "vuex";
// 使用import的方式是将包里所有的东西全部引入，如果只需要部分内容的话，这样做不推荐
// import _ from 'lodash'
import throttle from "lodash/throttle";

export default {
  name: "TypeNav",
  data() {
    return {
      currentIndex: -1,
      // 一开始true是为了首页要展示
      isShow: true,
    };
  },
  // 组件挂在完毕后，向服务器请求数据并保存在store中
  mounted() {

    /**
     * 学到了,(公共)全局组件在不同模块共用的时候,想要在不同模块控制显示与隐藏
     * 可以在mounted挂载时用变量进行判断
     * */
    if (this.$route.path !== "/home") {
      this.isShow = false;
    }
  },
  computed: {
    ...mapState({
      /**
       * vuex提供了一个好用的函数，用于mapState对象形式写法 (store)=>{}
       *
       * */
      categoryList: (state) => {
        //  console.log(state.home.categoryList);
        return state.home.categoryList;
      },
    }),
  },
  methods: {
    /**
     * (1) 学到了，想要用_.throttle赋值给changeIndex，可以使用ES5的k-v写法
     * 传的参数就可以放到，value函数里面
     * (2) 注意，回调函数最好不要写成箭头函数，会出现上下文this问题
     * 这里调用者为 _ ，因此this是 _ ，而我要的是当前Vue实例里面的，因此我调整为throttle按需引入就行了
     * this就是当前vue实例
     * (3) 这里节流50ms，不能节流太过分
     * */
    // changeIndex: _.throttle(function(index){
    //     this.currentIndex = index;
    // },50),
    changeIndex: throttle(function (index) {
      this.currentIndex = index;
    }, 20),

    leaveIndex() {
      this.currentIndex = -1;
      if (this.$route.path !== "/home") {
        this.isShow = false;
      }
    },
    // 注意函数默认是有个event参数的，就算调用的地方不写
    goSearch(event) {
      /**
       * 分析：点击导航Search模块，并携带参数name&id，Search收到之后向服务器发送请求收到后并展示
               路由跳转如果使用 声明式导航---Router-link，会带来一个问题，Router-link是个组件，循环有那么多路由要跳转，就要生成那么多组件，很耗内存，而且组件还涉及到页面的渲染，这样一来页面很容易出现卡顿现象
               那只能用编程式导航，但是编程式导航又涉及到回调函数，太多回调函数也不好，能不能只有一个回调函数？
               事件委派可以，但是事件委派又会带来新的问题，
       * 委派给父元素,那说明有很多子元素(a div dl dt...),无法确认点击的是a标签
       * 因为要a标签才需要跳转 ---- 添加自定义属性categoryname,从dataset中去获取,如果有则是a标签
       * 就算确定了是a标签,那如何把两个参数获取来跳转?
       * 因为所有的name都叫categoryname,刚好name就从这里面获取,那id的话也用同样的方法
       * 添加自定义属性,能取到就刚好赋值给id
       * */
      /**
       * dataset里面是每个目标节点存放所有用户自定义属性的地方,而且自定义属性名字浏览器统一规范成字母小写
       * 注意想要在dataset里面去取,得把自定义名字格式命为: data-xxx
       * */
      let element = event.target;
      console.log(element);
      //  因为上线的项目请求服务器就已经规定好了id是有1 2 3id的因此要自定义出区分的id
      const { categoryname, category1id, category2id, category3id } =
        element.dataset;
      console.log(categoryname);

      if (categoryname) {
        // 我靠,注意路由的name必须为是双引号!
        const location = { name: "search" };
        //  穿的参数是大驼峰,而全部小写的是指的是自定义书信
        const query = { categoryName: categoryname };
        if (category1id) {
          query.category1Id = category1id;
        } else if (category2id) {
          query.category2Id = category2id;
        } else if (category3id) {
          query.category3Id = category3id;
        }
        console.log(location, query);
        location.query = query;
        // 增加合并参数的写法(这下parmas和query参数都带过去了)
        if(this.$route.params){
          location.params = this.$route.params
        }
        this.$router.push(location);
      }
    },
  },
};
</script>

<style lang="less" scoped>
.type-nav {
  border-bottom: 2px solid #e1251b;

  .container {
    width: 1200px;
    margin: 0 auto;
    display: flex;
    position: relative;

    .all {
      width: 210px;
      height: 45px;
      background-color: #e1251b;
      line-height: 45px;
      text-align: center;
      color: #fff;
      font-size: 14px;
      font-weight: bold;
    }

    .nav {
      a {
        height: 45px;
        margin: 0 22px;
        line-height: 45px;
        font-size: 16px;
        color: #333;
      }
    }

    .sort {
      position: absolute;
      left: 0;
      top: 45px;
      width: 210px;
      height: 461px;
      position: absolute;
      background: #fafafa;
      z-index: 999;

      .all-sort-list2 {
        .item {
          h3 {
            line-height: 30px;
            font-size: 14px;
            font-weight: 400;
            overflow: hidden;
            padding: 0 20px;
            margin: 0;

            a {
              color: #333;
            }
          }

          .item-list {
            display: none;
            position: absolute;
            width: 734px;
            min-height: 460px;
            _height: 200px;
            background: #f7f7f7;
            left: 210px;
            border: 1px solid #ddd;
            top: 0;
            z-index: 9999 !important;

            .subitem {
              float: left;
              width: 650px;
              padding: 0 4px 0 8px;

              dl {
                border-top: 1px solid #eee;
                padding: 6px 0;
                overflow: hidden;
                zoom: 1;

                &.fore {
                  border-top: 0;
                }

                dt {
                  float: left;
                  width: 54px;
                  line-height: 22px;
                  text-align: right;
                  padding: 3px 6px 0 0;
                  font-weight: 700;
                }

                dd {
                  float: left;
                  width: 415px;
                  padding: 3px 0 0;
                  overflow: hidden;

                  em {
                    float: left;
                    height: 14px;
                    line-height: 14px;
                    padding: 0 8px;
                    margin-top: 5px;
                    border-left: 1px solid #ccc;
                  }
                }
              }
            }
          }

          &:hover {
            .item-list {
              display: block;
            }
          }
        }

        .curr {
          background-color: skyblue;
        }
      }
    }
 
    .sort-enter{
      height: 0;
    }

    .sort-enter-to{
      height: 461px;
    }

    .sort-enter-active{
      transition: all .5s linear;
    }
  }
}
</style>
